package rothag.models;

import rothag.models.monuments.Monument;
import rothag.models.developpement.Developpement;
import rothag.enums.TypeDes;
import java.util.ArrayList;
import rothag.models.ressources.Bois;
import rothag.models.ressources.FerDeLance;
import rothag.models.ressources.Pierre;
import rothag.models.ressources.Poterie;
import rothag.models.ressources.Ressource;
import rothag.models.ressources.Tissu;

/**
 * Implémentation de l'interface du joueur
 * @version 0.1
 * @author gulian.lorini
 */
public class Joueur extends ModelBase implements JoueurInterface {

    private String nom;
    private int score;
    private int piece;
    private int nourriture;
    private int bateau;
    private int ouvrier;
    private int crane;
    private int nbLancesAurorises;
    private ArrayList<TypeDes> listeDes;
    private ArrayList<String> listeActions;
    private Bois bois;
    private Pierre pierre;
    private Poterie poterie;
    private Tissu tissu;
    private FerDeLance fer;
    private ArrayList<VilleInterface> listeVilles;
    private ArrayList<Developpement> listeDeveloppements;
    private ArrayList<MonumentJoueurInterface> listeMonumentJoueur;
    private int nbVilleConstruite;
    private int nbMonumentConstruit;
    private int nbBateauConstruit;

    /**
     * Constructeur du joueur
     * @param nom Nom du joueur
     * @param listeMonument Liste des monuments possibles
     */
    public Joueur(String nom, ArrayList<Monument> listeMonument) {

        this.nom = nom;
        this.bateau = 0;
        this.score = 0;
        this.piece = 0;
        this.nourriture = 3;
        this.nbLancesAurorises = 3;
        this.ouvrier = 0;
        this.crane = 0;

        // Construction
        nbVilleConstruite = 0;
        nbMonumentConstruit = 0;
        nbBateauConstruit = 0;

        // Ressources
        bois = new Bois();
        pierre = new Pierre();
        poterie = new Poterie();
        tissu = new Tissu();
        fer = new FerDeLance();

        // Villes
        listeVilles = new ArrayList<VilleInterface>();
        listeVilles.add(new Ville(3));
        listeVilles.add(new Ville(4));
        listeVilles.add(new Ville(5));
        listeVilles.add(new Ville(6));

        // Monuments
        listeMonumentJoueur = new ArrayList<MonumentJoueurInterface>();
        if (listeMonument != null) {
            for (Monument monument : listeMonument) {
                listeMonumentJoueur.add(new MonumentJoueur(this, monument));
            }
        }

        // Développements
        listeDeveloppements = new ArrayList<Developpement>();

        // Dés
        listeDes = new ArrayList<TypeDes>();

        // Logs
        listeActions = new ArrayList<String>();
        listeActions.add("<b>========================<br>Joueur " + nom + " créé<br>========================</b>");
    }

    /**
     * Retourne la liste des développements du joueur
     * @return Liste de développements
     */
    public ArrayList<Developpement> getListeDeveloppements() {
        return listeDeveloppements;
    }

    /**
     * Retourne la liste des monuements du joueur
     * @return Liste de MonumentJoueur
     */
    public ArrayList<MonumentJoueurInterface> getListeMonumentJoueur() {
        return listeMonumentJoueur;
    }

    /**
     * Retourne la liste des villes du joueur
     * @return Liste de villes
     */
    public ArrayList<VilleInterface> getListeVilles() {
        return listeVilles;
    }

    /**
     * Retourne la liste des actions du joueur
     * @return Liste d'actions sous forme de String
     */
    public ArrayList<String> getListeActions() {
        return listeActions;
    }

    /**
     * Retourne le nombre de bateaux du joueur
     * @return Nombre de bateaux
     */
    public int getBateau() {
        return bateau;
    }

    /**
     * Met à jour le nombre de bateaux du joueur
     * @param bateau Nouvelle valeur
     */
    public void setBateau(int bateau) {
        this.bateau = bateau;
    }

    /**
     * Retourne le nombre de nourriture du joueur
     * @return Nombre de nourriture
     */
    public int getNourriture() {
        return nourriture;
    }

    /**
     * Met à jour le nombre de nourriture
     * @param nourriture Nouvelle valeur
     */
    public void setNourriture(int nourriture) {
        this.nourriture = nourriture;
    }

    /**
     * Retourne la ressource du joueur à partie de sa classe
     * @param ressource Classe de la ressource
     * @return Ressource correspondante à la classe
     */
    public Ressource getRessource(Class ressource) {
        if (ressource == Bois.class) {
            return getBois();
        } else if (ressource == Pierre.class) {
            return getPierre();
        } else if (ressource == Tissu.class) {
            return getTissu();
        } else if (ressource == Poterie.class) {
            return getPoterie();
        } else if (ressource == FerDeLance.class) {
            return getFer();
        }
        return null;
    }

    /**
     * Retourne la ressource Bois
     * @return Bois
     */
    public Bois getBois() {
        return bois;
    }

    /**
     * Retourne la ressrouce Fer de lance
     * @return FerDeLance
     */
    public FerDeLance getFer() {
        return fer;
    }

    /**
     * Retourne la ressource Pierre
     * @return Pierre
     */
    public Pierre getPierre() {
        return pierre;
    }

    /**
     * Retourne la ressource Poterie
     * @return Poterie
     */
    public Poterie getPoterie() {
        return poterie;
    }

    /**
     * Retourne la ressource Tissu
     * @return Tissu
     */
    public Tissu getTissu() {
        return tissu;
    }

    /**
     * Retourne le nombre de pièce
     * @return Nombre de pièces
     */
    public int getPiece() {
        return piece;
    }

    /**
     * Met à jour le nombre de pièces
     * @param piece Nouvelle valeur
     */
    public void setPiece(int piece) {
        this.piece = piece;
    }

    /**
     * Retourne le score du joueur
     * @return Score du joueur
     */
    public int getScore() {
        return score;
    }

    /**
     * Met à jour le score du joueur
     * @param score Nouvelle valeur
     */
    public void setScore(int score) {
        this.score = score;
    }

    /**
     * Retourne le nom du joueur
     * @return Nom du joueur
     */
    public String getNom() {
        return nom;
    }

    /**
     * Retourne la liste des dés du joueur
     * @return Liste de dés
     */
    public ArrayList<TypeDes> getListeDes() {
        return listeDes;
    }

    /**
     * Met à jour la liste des dés du joueur
     * @param listeDes Nouvelle liste
     */
    public void setListeDes(ArrayList<TypeDes> listeDes) {
        this.listeDes = listeDes;
    }

    /**
     * Retourne le nombre de villes construites du joueur
     * @return Le nombre de villes construite
     */
    public int getNbVilles() {
        if (listeVilles != null) {
            int nb = 3;

            for (VilleInterface v : listeVilles) {
                if (v.getNombreOuvrierNecessaire() == v.getNombreOuvrierSelectionne()) {
                    nb++;
                }
            }

            return nb;
        } else {
            return 0;
        }
    }

    /**
     * Retourne le nombre de lancés autorisé pour le joueur
     * @return Nombre de lancés autorisés
     */
    public int getNbLancesAurorises() {
        return nbLancesAurorises;
    }

    /**
     * Retourne le nombre de crânes du joueur
     * @return Nombre de crânes
     */
    public int getCrane() {
        return crane;
    }

    /**
     * Met à jour le nombre de crânes
     * @param crane Nouvelle valeur
     */
    public void setCrane(int crane) {
        this.crane = crane;
    }

    /**
     * Retourne le nombre d'ouvriers du joueur
     * @return Nombre d'ouvriers
     */
    public int getOuvrier() {
        return ouvrier;
    }

    /**
     * Met à jour le nombre d'ouvriers
     * @param ouvrier Nouvelle valeur
     */
    public void setOuvrier(int ouvrier) {
        this.ouvrier = ouvrier;
    }

    /**
     * Retourne si un développement est réalisé par le joueur
     * @param developpement Développement à chercher
     * @return Vrai si le développement est réalisé
     */
    public boolean estRealiseDeveloppement(Developpement developpement) {
        boolean devAchete = false;
        for (Developpement d : listeDeveloppements) {
            if (d == developpement) {
                devAchete = true;
                break;
            }
        }

        return devAchete;
    }

    /**
     * Permet d'ajouter un développement réalisé au joueur
     * @param dev Développement
     */
    public void setDeveloppementRealise(Developpement dev) {
        listeDeveloppements.add(dev);
    }

    /**
     * Retourne le nombre de bateaux construit pendant le tour
     * @return Nombre de bateaux
     */
    public int getNbBateauConstruit() {
        return nbBateauConstruit;
    }

    /**
     * Met à jour le nombre de bateaux construit pendant le tour
     * @param nbBateauConstruit Nouvelle valeur
     */
    public void setNbBateauConstruit(int nbBateauConstruit) {
        this.nbBateauConstruit = nbBateauConstruit;
    }

    /**
     * Retourne le nombre de monuments construit pendant le tour
     * @return Nombre de monuments
     */
    public int getNbMonumentConstruit() {
        return nbMonumentConstruit;
    }

    /**
     * Met à jour le nombre de monuements construit pendant le tour
     * @param nbMonumentConstruit Nouvelle valeur
     */
    public void setNbMonumentConstruit(int nbMonumentConstruit) {
        this.nbMonumentConstruit = nbMonumentConstruit;
    }

    /**
     * Retourne le nombre de villes construites pendant le tour
     * @return Nombre de monuments
     */
    public int getNbVilleConstruite() {
        return nbVilleConstruite;
    }

    /**
     * Met à jour le nombre de villes construites pendant le tour
     * @param nbVilleConstruite Nouvelle valeur
     */
    public void setNbVilleConstruite(int nbVilleConstruite) {
        this.nbVilleConstruite = nbVilleConstruite;
    }

    /**
     * Retourne la quantité totale des ressources du joueur
     * @return Quantité totale des ressources
     */
    public int getSommeRessource() {
        int somme = bois.getQuantite();
        somme += pierre.getQuantite();
        somme += poterie.getQuantite();
        somme += tissu.getQuantite();
        somme += fer.getQuantite();

        return somme;
    }

    /**
     * Retourne le nombre total des ressources du joueur
     * @return Nombre total des ressources
     */
    public int getNbTotalRessources() {

        int somme = bois.getIndice();
        somme += pierre.getIndice();
        somme += poterie.getIndice();
        somme += tissu.getIndice();
        somme += fer.getIndice();

        return somme;
    }

    /**
     * Retourne le MonumentJoueurInterface correspondant à un monuement
     * @param monument Monuement à chercher
     * @return MonumentJoueurInterface
     */
    public MonumentJoueurInterface getMonumentJoueur(Class monument) {
        MonumentJoueurInterface monumentJoueur = null;

        for (MonumentJoueurInterface m : listeMonumentJoueur) {
            if (m.getMonument().getClass() == monument) {
                monumentJoueur = m;
                break;
            }
        }

        return monumentJoueur;
    }
}
